<?php
namespace My\Controller;

use Utuo\BackgroundController;
use My\Model\DeliveryModel;
use Utuo\DBRW;
use Utuo\Region;

class DeliveryTplController extends BackgroundController {
	
	
	public function _initialize() {
		$this->setControllerTitle('运费模板管理');
		$this->setActionTitle(array(
			'index' => '运费模板管理',
			'add' => '添加运费模板',
			'modify' => '修改运费模板',
			'recycle' => '回收站',
		));
		$this->setActionNav(array(
			'index',
			'add',
			'recycle'
		));
	}
	
	/**
	 * tplConfig 格式
	 * @see \Utuo\BackgroundController::indexAction()
	 */
	public function indexAction() {
		$deliveryTpl = M("DeliveryTpl")->where(array("cid" => $this->aid, "is_deleted" => 0))->select();
		$this->bindConfig( $deliveryTpl, 1 );
		$this->assign("deliveryTpl", $deliveryTpl);
		$this->assign("methods", DeliveryModel::$METHOD);
		$this->display();
	}
	
	public function recycleAction() {
		$deliveryTpl = M("DeliveryTpl")->where(array("cid" => $this->aid, "is_deleted" => 1))->select();
		$this->bindConfig( $deliveryTpl, 1 );
		$this->assign("deliveryTpl", $deliveryTpl);
		$this->assign("methods", DeliveryModel::$METHOD);
		$this->display();
	}
	
	/**
	 * 添加
	 * @see \Utuo\BackgroundController::addAction()
	 */
	public function addAction() {
		if ( IS_POST ) {
			$result = $this->saveAction() and !$result['error'] and redirect(__CONTROLLER__.'/modify/id/'.$result['tplId'] );
			$config = $result['config'];
		} else {
			$config = $this->getConfig(array());
		}
		$areaGroup = Region::getAreaGroup();
		$this->assign("presetJson", json_encode(array("list" => $config)) );
		$this->assign("areaGroup", json_encode($areaGroup));
		$this->assign("methods", DeliveryModel::$METHOD);
		$this->display("save");
	}
	
	
	/**
	 * 修改
	 * @see \Utuo\BackgroundController::modifyAction()
	 */
	public function modifyAction() {
		DBRW::openAndClose(0);
		$id = I("id", 0, "intval");
		if ( IS_POST ) {
			$result = $this->saveAction() and !$result['error'] and redirect(__CONTROLLER__.'/modify/id/'.$result['tplId']);
		}
		
		/* 获得设置 JSON */
		$deliveryTpl = M("DeliveryTpl")->where(array("cid" => $this->aid, "id" => $id))->find();
		if ( !$result ) {
			$this->bindConfig($deliveryTpl);
			$config = $this->getConfig($deliveryTpl['tplConfig']);
			unset($deliveryTpl['tplConfig']);
		} else {
			$config = $result['config'];
		}
		DBRW::openAndClose(1);
		
		$frmLoc = explode(',', $deliveryTpl['frmLoc']);
		$presetData = array(
							'id' => $deliveryTpl['id'],
							'name' => $deliveryTpl['name'],
							'address' => $deliveryTpl['address'],
							'provCode' => $frmLoc[0], 'cityCode' => $frmLoc[1], 'areaCode' => $frmLoc[2], 
							'list' => $config, );
		$areaGroup = Region::getAreaGroup();
		$this->assign("presetJson", json_encode($presetData) );
		$this->assign("areaGroup", json_encode($areaGroup));
		$this->assign("methods", DeliveryModel::$METHOD);
		$this->assign("deliveryTpl", $deliveryTpl);
		$this->display("save");
	}
	
	/**
	 * 模板保存
	 * @see \Utuo\BackgroundController::saveAction()
	 * @param deliveryJson string 
	 *    '{
	 *	        "express": {
	 *	            "enabled": true,
	 *	            "start": "1",
	 *	            "postage": "10.00",
	 *	            "plus": 1,
	 *	            "postageplus": "1.00",
	 *	            "delivery": "express",
	 *	            "special": [{
	 *	                //"areas": ["330000", "360000", "340000"], 暂不支持地区选择
	 *	                "delivery": "express",
	 *	                "plus": "1",
	 *	                "postage": "10.00",
	 *	                "postageplus": "1.00",
	 *	                "provCodes": [],
	 *	                "start": "1",
	 *	            }]
	 *	        },
	 *			// ... ...
	 *	    }'
	 */
	public function saveAction() {
		$result = $this->submitPost();
		if ( IS_AJAX ) {
			if ( $result['error'] ) {
				$this->ajaxError($result['msg'], json_encode($result['config']));
			} else {
				$this->ajaxSuccess($result['msg'], json_encode($result['config']));
			}
		} else {
			if ( ACTION_NAME !== "save" ) {
				return $result;
			} else {
				// ... ...
			}
		}
	}
	
	public function submitPost() {
		$result = array(
			'error' => 0,
			'msg' => '', // 总错误信息
			'config' => '', // 错误信息
			'tplId' => 1, // 模板id
			'do' => '', // add save
		);
		
		$d = D('DeliveryTpl');
		$tplData = $d->create();
		if ( !$tplData ) {
			$result['msg'] = $d->getError();
			$result['error'] = 1;
			return $result;
		}

		$res = $this->getDelivery();
		$result['config'] = $res['data'];
		if ( $res['error'] ) {
			$result['msg'] = "运送方式配置有误，请检查后再提交";
			$result['error'] = 1;
			return $result;
		}
		
		$frmLoc = array();
		$frmLoc[] = I("provCode", 0);
		$frmLoc[] = I("cityCode", 0);
		$frmLoc[] = I("areaCode", 0);
		$d->frmLoc = join(",", $frmLoc);
		if (empty($_REQUEST['id'])) {
			$result['do'] = 'add';
			$tplId = $d->add();
			if ( $tplId ) {
				$result['msg'] = "添加成功";
				$result['tplId'] = $tplId;
				$this->saveConfig($tplId, $result['config']);
			} else {
				$result['error'] = 1;
				$result['msg'] = "添加失败";
			}
		} else {
			$result['do'] = 'save';
			$result['tplId'] = $d->id;
			if (false !== $d->save()) {
				$result['msg'] = "修改成功";
				$this->saveConfig($result['tplId'], $result['config']);
			} else {
				$result['error'] = 1;
				$result['msg'] = "修改失败！";
			}
		}
		
		return $result;
	}
	
	/**
	 * 保存配置(验证成功的数据)
	 * @param unknown $config
	 */
	private function saveConfig($tplId, $config ) {
		foreach ( $config as $tag => $cfg ) {
			$existCfg = M('DeliveryTplConfig')->where(array('cid'=>$this->aid, 'tpId'=>$tplId, 'typeId'=>$cfg['deliveryId']))->find();
			$data = array(
						'cid' => $this->aid,
						'tpId' => $tplId,
						'typeId' => $cfg['deliveryId'],
						'config' => serialize($cfg),
						'selected' => $cfg['enabled']?true:false,
					);
			if ( $existCfg ) {
				$data['id'] = $existCfg['id'];
				M('DeliveryTplConfig')->save($data);
			} else {
				M('DeliveryTplConfig')->add($data);
			}
		}
	}
	
	/**
	 * 获得运费配置
	 */
	private function getDelivery() {
		$result = array('error' => 0, 'data' => null);
		$deliveryJson = I('list');
		$delivery = json_decode(htmlspecialchars_decode($deliveryJson), true) or ($result['error'] = 1);
		foreach ( $delivery as $tag => &$v ) {
			$message = array();
			$v['deliveryId'] = DeliveryModel::getTypeId($v['delivery']);
			$v['errors'] = $this->checkItem($v, $message); // 字段是否错误的信息
			$v['message'] = array_values($message); // 错误信息
			$specialmessage = array();
			foreach ( $v['special'] as $i => &$special ) {
				$special['errors'] = $this->checkItem($special, $specialmessage);
			}
			$v['specialmessage'] = array_values($specialmessage);
			($v['message'] or $v['specialmessage']) and $result['error'] = true;
		}
		$result['data'] = $delivery;
		return $result;
	}
	
	/**
	 * 验证配置项
	 * @param unknown $special
	 * @param unknown $specialmessage
	 * @return boolean|multitype:boolean
	 */
	private function checkItem( $special, &$specialmessage ) {
		$fields = array(
			'start' => !1,
			'postage' => !1,
			'plus' => !1,
			'postageplus' => !1,
		);
		static $defined = 0;
		if ( !$defined ) {
			function start( $v ) {
				return !is_integer($v) or $v*1 <= 0 ? '首件应输入1至9999的数字' : '';
			}
			function postage( $v ) {
				return !is_numeric($v) or !($v*1 >=0 and $v*1<=999.99) ? '首费应输入0.00至999.99的数字' : '';
			}
			function plus( $v ) {
				return !is_integer($v) or $v*1 <= 0 ? '续件应输入1至9999的数字' : '';
			}
			function postageplus( $v ) {
				return !is_numeric($v) or !($v*1 >=0 and $v*1<=999.99) ? '续费应输入0.00至999.99的数' : '';
			}
			$defined = 1;
		}
		if ( !isset($special['special']) and !$special['provCodes'] ) {
			key_exists("provCodes", $specialmessage) or $specialmessage["provCodes"] = "未选择配送省份";
		}
		foreach ( $fields as $k => $v ) {
			function_exists($k) and $errMsg = $k( $special[$k] ) ;
			if ( $errMsg ) {
				$fields[$k] = !0; 
				key_exists($k, $specialmessage) or $specialmessage[$k] = $errMsg;
			}
		}
		return $fields;
	}
	
	/**
	 * 绑定模板配置
	 * @param unknown $deliveryTpl 模板数据或单个模板
	 * @return
	 *  0 => array( // 模板
	 *    'id' => '', // 模板id
	 * 	  'tplConfig' => array( // 模板配置
	 * 		 0 => array(
	 * 			'tpId' => 1,
	 * 			'typeId' => 1,
	 * 			'selected' => 0,
	 * 			'config' => array( // express配置信息
	 *     			'enabled' => true,
	 *				'delivery' =>  'express',
	 *				'start' => 1,
	 *				'postage' => '',
	 *				'plus' => 1,
	 *				'postageplus' => '',
	 *				'special' => array(
	 *					0 => array(
	 *						'provCodes' => array(
	 *									  	1000,1001
	 *								   	),
	 *						'start' => 1,
	 *						'postage' => '',
	 *						'plus' => 1,
	 *						'postageplus' => '',
	 *					)
	 *					// ... ...
	 *				)
	 * 			),
	 * 		 ),
	 * 		// ... ...
	 * 	  ),
	 *  )
	 */
	private function bindConfig( &$deliveryTpl, $details = 0 ) {
		reset($deliveryTpl);
		if ( is_numeric( key( $deliveryTpl ) ) and key( $deliveryTpl ) === 0 ) {
			$dTpl = &$deliveryTpl;
		} else {
			$dTpl = array(
					&$deliveryTpl,
			);
		}
		foreach ( $dTpl as &$tpl ) { 
			if ( $tpl ) {
				$tpl['tplConfig'] = M("DeliveryTplConfig")->where(array('tpId' => $tpl['id']))->select();
				foreach ( $tpl['tplConfig'] as &$cfgItem ) {
					$cfgItem['config'] = unserialize( $cfgItem['config'] );
					if ( $details ) {
						foreach ( $cfgItem['config']['special'] as &$v ) {
							$names = M("CnProvince")->where(array('code' => array("in", $v['provCodes'])))->getField('name', true);
							$v['provNames'] = join(",", $names);
						}
					}
				}
			} 
		}
	}
	
	/**
	 * 模板配置信息初始设置
	 * @param unknown $deliveryTpl
	 * @assign presetJson
	 * array(
	 *  'list' => array(
	 *     	'1' => array(
	 *     		'enabled' => true,
	 *			'delivery' =>  'express',
	 *			'start' => 1,
	 *			'postage' => '',
	 *			'plus' => 1,
	 *			'postageplus' => '',
	 *			'special' => array(
	 *				0 => array(
	 *					'areas' => array(
	 *						1000,1001
	 *					),
	 *					'start' => 1,
	 *					'postage' => '',
	 *					'plus' => 1,
	 *					'postageplus' => '',
	 *				)
	 *			)
	 *		),
	 *		... ...
	 *   )
	 * )
	 */
	private function getConfig( $deliveryTplConfig = array() ) {
		$list = array();
		foreach ( $deliveryTplConfig as &$v ) {
			$list[$v['typeId']] = $v['config'];
			if ( $list[$v['typeId']] ) {
				$list[$v['typeId']]['enabled'] = !!$v['selected']*1;
			}
		}
		ksort($list);
		return $list;
	}
	
} 